<?php

/**
 * Class YimeUpload
 */
class YimeUpload
{

    public static function getUploadToDir($uploadToDir = './upload')
    {
        if (!file_exists($uploadToDir))
            mkdir($uploadToDir);
        $uploadToDir = $uploadToDir . '/' . date("Y");
        if (!file_exists($uploadToDir))
            mkdir($uploadToDir);
        $uploadToDir = $uploadToDir . '/' . date("m");
        if (!file_exists($uploadToDir))
            mkdir($uploadToDir);
        $uploadToDir = $uploadToDir . '/' . date("d");
        if (!file_exists($uploadToDir))
            mkdir($uploadToDir);

        return $uploadToDir;
    }

    /**
     * @param int $userId
     * @param string $fileUniName
     * @param string $fileName
     * @param string $fileExt
     * @param string $tmpFileUrl
     * @param int $chunk
     * @param int $chunks
     * @param string $uploadToDir
     * @throws NeedMoreDataException
     * @return File
     */
    public static function uploadFile($userId, $fileUniName, $fileName, $fileExt, $tmpFileUrl, $chunk, $chunks, $uploadToDir = './upload')
    {
        /** @var CI $CI */
        $CI =& get_instance();
        $CI->load->helper('file');
        $CI->load->helper('security');

        $mergeFileUrl = self::getUploadToDir($uploadToDir) . '/' . $fileUniName . '.merge';
        if ($chunk === 0)
            write_file($mergeFileUrl, read_file($tmpFileUrl), 'w');
        else
            write_file($mergeFileUrl, read_file($tmpFileUrl), 'a');

        if (!$chunks || $chunk == $chunks - 1) {
            //文件已上传完整

            $thatFile = self::saveFile($userId, $fileName, $fileExt, $mergeFileUrl, $uploadToDir);

            return $thatFile;
        }

        throw new NeedMoreDataException('文件未接收完整，请求继续发送数据');
    }

    /**
     * @param int $userId
     * @param string $fileUniName
     * @param string $fileName
     * @param string $fileExt
     * @param string $tmpFileUrl
     * @param int $chunk
     * @param int $chunks
     * @param array|bool $cropParam
     * @param string $uploadToDir
     * @return File
     * @throws ParaException
     * @throws Exception
     */
    public static function uploadAvatar($userId, $fileUniName, $fileName, $fileExt, $tmpFileUrl, $chunk, $chunks, $cropParam = false, $uploadToDir = './upload')
    {
        /** @var CI $CI */
        $CI =& get_instance();
        $CI->load->helper('file');
        $CI->load->helper('security');

        $thatFile = self::uploadFile($userId, $fileUniName, $fileName, $fileExt, $tmpFileUrl, $chunk, $chunks, $uploadToDir);
        if (!$thatFile)
            throw new Exception('文件上传失败');

        if ($cropParam === false || !is_array($cropParam))
            throw new ParaException('参数不正确');

        $crop_x1 = isset($cropParam['crop_x1']) ? $cropParam['crop_x1'] : false;
        $crop_y1 = isset($cropParam['crop_y1']) ? $cropParam['crop_y1'] : false;
        $crop_x2 = isset($cropParam['crop_x2']) ? $cropParam['crop_x2'] : false;
        $crop_y2 = isset($cropParam['crop_y2']) ? $cropParam['crop_y2'] : false;
        $crop_w  = isset($cropParam['crop_w']) ? $cropParam['crop_w'] : false;
        $crop_h  = isset($cropParam['crop_h']) ? $cropParam['crop_h'] : false;


        if ($crop_x1 === false || $crop_y1 === false || $crop_x2 === false || $crop_y2 === false || $crop_w === false || $crop_h === false) {
            throw new ParaException('裁剪参数不正确');
        }

        $tmpFileUrl = $thatFile->getUrl() . '_tmp' . $fileExt;

        $CI->load->library('image_lib');

        $config = array(
            'image_library'  => 'gd2',
            'source_image'   => $thatFile->getUrl(),
            'quality'        => '90',
            'create_thumb'   => false,
            'new_image'      => $tmpFileUrl,
            'maintain_ratio' => false,
        );

        $config['x_axis'] = $crop_x1;
        $config['y_axis'] = $crop_y1;
        $config['width']  = $crop_w;
        $config['height'] = $crop_h;

        $CI->image_lib->initialize($config);
        if (!$CI->image_lib->crop()) {
            throw new Exception($CI->image_lib->display_errors());
        }

        $config['source_image'] = $tmpFileUrl;
        $config['width']        = 256;
        $config['height']       = 256;
        $CI->image_lib->initialize($config);
        if (!$CI->image_lib->resize()) {
            throw new Exception($CI->image_lib->display_errors());
        }

        $thatFile = self::saveFile($userId, $fileName, $fileExt, $tmpFileUrl, $uploadToDir);

        return $thatFile;
    }

    /**
     * @param int $userId
     * @param string $fileName
     * @param string $fileExt
     * @param string $tmpFileUrl
     * @param string $uploadToDir
     * @return File
     */
    public static function saveFile($userId, $fileName, $fileExt, $tmpFileUrl, $uploadToDir = './upload')
    {
        /** @var CI $CI */
        $CI =& get_instance();
        $CI->load->helper('file');
        $CI->load->helper('security');

        //计算哈希值
        $fileHash    = do_hash(read_file($tmpFileUrl));
        $fileFullUrl = self::getUploadToDir($uploadToDir) . '/' . $fileHash . $fileExt;

        //判断文件是否存在
        if (file_exists($fileFullUrl)) {
            delete_files($tmpFileUrl);
        } else {
            rename($tmpFileUrl, $fileFullUrl);
        }

        $fileInfo = get_file_info($fileFullUrl);

        $thatFile = new File();
        $thatFile->setName($fileName);
        $thatFile->setHash($fileHash);
        $thatFile->setType(get_mime_by_extension($fileFullUrl));
        $thatFile->setSize($fileInfo['size']);
        $thatFile->setTime(date("Y-m-d H:i:s", $fileInfo['date']));
        $thatFile->setUrl($fileFullUrl);
        $thatFile->setUserId($userId);

        $thatFile = File_Model::add($thatFile);

        return $thatFile;
    }


}